package br.com.equipe1.model.service;

import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import br.com.equipe1.enumeration.TipoEstado;
import br.com.equipe1.model.Empresa;
import br.com.equipe1.utils.FacesUtils;

public class EmpresaService {
	
	private final static String PERSISTENCE_UNIT_NAME = "Projeto";
	private final static String RAMO_ATUACAO = "ramoAtuacao";
	private final static String BAIRRO = "bairro";
	private final static String CIDADE = "cidade"; 
	private final static String UF = "uf";
	private EntityManager entityManager;
	private EntityManagerFactory factory;
	
	public EmpresaService() {
		factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
	}

	public EntityManager getEntityManager() {
		return factory.createEntityManager();
	}
	
	public void salvar(Empresa empresa){
		try {
			entityManager = getEntityManager();
			entityManager.getTransaction().begin();
			if(empresa.getId() == null){
				entityManager.persist(empresa);
				FacesUtils.info("Empresa "+empresa.getNome()+" adicionado com sucesso.");
			} else {
				entityManager.merge(empresa);
				FacesUtils.info("Empresa "+empresa.getNome()+" atualizado com sucesso.");
			}
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			FacesUtils.error("Erro ao salvar empresa. Contate administrador");
			e.printStackTrace();
			entityManager.getTransaction().rollback();
		} finally {
			entityManager.close();
		}
	}
	
	public void remover(Integer id){
		try {
			entityManager = getEntityManager();
			entityManager.getTransaction().begin();
			Empresa empresa = entityManager.getReference(Empresa.class, id);
			entityManager.remove(empresa);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			FacesUtils.error("Erro ao remover empresa. Contate administrador");
			e.printStackTrace();
			entityManager.getTransaction().rollback();
		} finally {
			entityManager.close();
		}		
	}
	
	@SuppressWarnings("unchecked")
	public List<Empresa> buscarTodos(){
		entityManager = getEntityManager();
		try{
			StringBuilder sql = new StringBuilder();
			sql.append(" SELECT emp FROM Empresa emp ");
			sql.append(" INNER JOIN FETCH emp.enderecoEmpresa ende ");
			sql.append(" INNER JOIN FETCH emp.ramoAtuacao ram ");
			sql.append(" LEFT JOIN FETCH emp.representante rep ");
			sql.append(" INNER JOIN FETCH rep.cargo car ");
			sql.append(" INNER JOIN FETCH rep.enderecoRepresentante er ");
			sql.append(" ORDER BY emp.nome ");
			return entityManager.createQuery(sql.toString()).getResultList();
		} finally {
			entityManager.close();
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Empresa> buscarPorFiltro(Map<String, Object> filtro){
		entityManager = getEntityManager();
		try{
			StringBuilder sql = new StringBuilder();
			sql.append(" SELECT emp FROM Empresa emp ");
			sql.append(" INNER JOIN FETCH emp.enderecoEmpresa ende ");
			sql.append(" INNER JOIN FETCH emp.ramoAtuacao ram ");
			sql.append(" LEFT JOIN FETCH emp.representante rep ");
			sql.append(" INNER JOIN FETCH rep.cargo car ");
			sql.append(" INNER JOIN FETCH rep.enderecoRepresentante er ");
			sql.append(" WHERE 1 = 1 ");
			sql.append(!isRamoAtuacaoNulo(filtro) ? " AND UPPER(ram.descricao) LIKE UPPER(:ramoAtuacao) " : "");
			sql.append(!isBairroNulo(filtro) ? " AND UPPER(ende.bairro) LIKE UPPER(:bairro) " : "");
			sql.append(!isCidadeNulo(filtro) ? " AND UPPER(ende.cidade) LIKE UPPER(:cidade) " : "");
			sql.append(!isUFNulo(filtro) ? " AND ende.uf = :uf " : "");
			sql.append(" ORDER BY emp.nome ");
			Query query =  entityManager.createQuery(sql.toString());
			if(!isRamoAtuacaoNulo(filtro)){
				query.setParameter(RAMO_ATUACAO, "%"+filtro.get(RAMO_ATUACAO).toString()+"%");
			}
			if(!isBairroNulo(filtro)){
				query.setParameter(BAIRRO, "%"+filtro.get(BAIRRO).toString()+"%");
			}
			if(!isCidadeNulo(filtro)){
				query.setParameter(CIDADE, "%"+filtro.get(CIDADE).toString()+"%");
			}
			if(!isUFNulo(filtro)){
				TipoEstado uf = (TipoEstado) filtro.get(UF);
				query.setParameter(UF, uf);
			}
			return query.getResultList();			
		} finally {
			entityManager.close();
		}
	}
	
	private boolean isRamoAtuacaoNulo(Map<String, Object> filtro){		
		return filtro.get(RAMO_ATUACAO) == "";
	}
	
	private boolean isBairroNulo(Map<String, Object> filtro){
		return filtro.get(BAIRRO) == "";
	}
	
	private boolean isCidadeNulo(Map<String, Object> filtro){
		return filtro.get(CIDADE) == "";
	}
	
	private boolean isUFNulo(Map<String, Object> filtro){
		return filtro.get(UF) == null;
	}
	

}
